<?php

declare(strict_types=1);

namespace App\Chat\Service;

use App\CustHub\Mapper\ChTalkSettingConfigMapper;
use App\CustHub\Model\ChTalkSettingConfig;
use FriendsOfHyperf\Lock\Exception\LockTimeoutException;
use Hyperf\DbConnection\Db;
use Mine\Abstracts\AbstractService;
use function FriendsOfHyperf\Lock\lock;
use function Hyperf\Support\optional;

class TalkSettingConfigService extends AbstractService
{
    public $mapper;

    public function __construct(ChTalkSettingConfigMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    public function getInfo(array $params): array
    {
        $info = $this->mapper->findByUid($params['uid']);
        if(empty($info)){
            $columns = Db::select("SHOW FULL COLUMNS FROM ch_talk_setting_config");

            $defaultConfig = [];
            foreach ($columns as $column) {
                $field = $column->Field;
                $default = $column->Default;

                // 跳过自增主键和时间字段
                if (in_array($field, ['id', 'created_at', 'updated_at'])) {
                    continue;
                }

                // UID 填当前用户
                if ($field === 'uid') {
                    $defaultConfig[$field] = $params['uid'];
                } else {
                    $defaultConfig[$field] = $default ?? '';
                }
            }
            return $defaultConfig;
        }
        return $info->toArray();
    }

    public function save(array $data): mixed
    {
        $lock = lock('talk_setting_config_save:' . $data['uid'],4);
        try {
            $lock->block(5);
            $info = ChTalkSettingConfig::query()
                ->where('uid',$data['uid'])
                ->first();
            if($info){
                $rst = $this->mapper->update($info->id,$data);
            }else{
                $rst = $this->mapper->save($data);
            }
            if($rst){
                $this->mapper->clearCache($data['uid']);
            }
            return $rst;
        } catch (LockTimeoutException $e) {
            // 无法获取锁...
            return false;
        } finally {
            optional($lock)->release();
        }
    }
}